{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "BwHR1frLWbAp"
   },
   "source": [
    "# WebocketClientWorker Tutorial\n",
    "\n",
    "This tutorial is a 2 notebook tutorial. The partner notebook is the notebook entitled `WebsocketServerWorker.ipynb` and is in the same folder as this notebook. You should execute this notebook AFTER you have executed the other one.\n",
    "\n",
    "In that tutorial, we'll demonstrate how to launch a WebsocketWorker server which will listen for PyTorch commands over a socket connection. In this tutorial, the two workers are connected via a socket connection on the localhost network.\n",
    "\n",
    "If you'd prefer to download this notebook and run it locally, you can do so via the `Download .ipynb` in the `File` dropdown field in this Google colab environment. \n",
    "\n",
    "Setup instructions: https://research.google.com/colaboratory/local-runtimes.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "LkAOFaq3WdCn"
   },
   "source": [
    "\n",
    "# Step -1: Copy This Notebook\n",
    "\n",
    "Go up to File -> Save A Copy in Drive\n",
    "\n",
    "This will let you execute the notebook (it won't let you execute this one by default)\n",
    "\n",
    "# Step 0: Install Dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 5154
    },
    "colab_type": "code",
    "id": "G58GV77oWgO-",
    "outputId": "b6080406-3e39-47b6-e39c-95709cd8d932"
   },
   "outputs": [],
   "source": [
    "# If not using local runtimes, uncomment out the following snippets where necessary.\n",
    "\n",
    "#! rm -rf /content/PySyft\n",
    "#! git clone https://github.com/OpenMined/PySyft.git\n",
    "# http://pytorch.org/\n",
    "#from os import path\n",
    "#from wheel.pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag\n",
    "\n",
    "#platform = '{}{}-{}'.format(get_abbr_impl(), get_impl_ver(), get_abi_tag())\n",
    "#cuda_output = !ldconfig -p|grep cudart.so|sed -e 's/.*\\.\\([0-9]*\\)\\.\\([0-9]*\\)$/cu\\1\\2/'\n",
    "#accelerator = cuda_output[0] if path.exists('/opt/bin/nvidia-smi') else 'cpu'\n",
    "\n",
    "#!pip3 install https://download.pytorch.org/whl/cu100/torch-1.1.0-cp36-cp36m-linux_x86_64.whl\n",
    "#!pip3 install https://download.pytorch.org/whl/cu100/torchvision-0.3.0-cp36-cp36m-linux_x86_64.whl\n",
    " \n",
    "import torch\n",
    "\n",
    "#!cd PySyft; pip3 install -r requirements.txt; pip3 install -r requirements_dev.txt; python3 setup.py install\n",
    "\n",
    "import os\n",
    "import sys\n",
    "\n",
    "#module_path = '/content/PySyft'  # You want './PySyft' to be on your sys.path\n",
    "#if module_path not in sys.path:\n",
    "#    sys.path.append(module_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "VnXF1hWxjtKr"
   },
   "outputs": [],
   "source": [
    "# Check sys.path\n",
    "#sys.path"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "qjuWR5W1WbAq"
   },
   "source": [
    "# Step 1: Hook Torch and Create Local Worker\n",
    "\n",
    "In this step, we hook PyTorch and initialize within the hook a client SocketWorker."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 334
    },
    "colab_type": "code",
    "id": "3Uiboh5tWbAs",
    "outputId": "32f16cbc-d65f-44cc-c4e6-611f98ee516b"
   },
   "outputs": [],
   "source": [
    "import syft\n",
    "from syft.workers.websocket_server import WebsocketServerWorker\n",
    "\n",
    "hook = syft.TorchHook(torch)\n",
    "\n",
    "local_worker = WebsocketServerWorker(\n",
    "                            host='localhost',\n",
    "                            hook=hook,\n",
    "                            id=0,\n",
    "                            port=8182,\n",
    "                            log_msgs=True,\n",
    "                            verbose=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "9xbDlCZEWbAz"
   },
   "source": [
    "# Step 2: Create Pointer to Remote Socket Worker\n",
    "\n",
    "In order to interact with a foreign worker over a socket connection, we need to create a pointer to it containing information on how to contact it. We set the is_pointer=True to signify that this Python object is not in fact a worker in and of itself but that it is merely a pointer to one over the network. We then inform our local worker about this pointer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 34
    },
    "colab_type": "code",
    "id": "pakbrhCuWbAz",
    "outputId": "ecab6f57-0eb0-4a06-ccb5-b581f4a65945"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Attaching Pointer to Socket Worker...\n"
     ]
    }
   ],
   "source": [
    "hook = syft.TorchHook(torch, local_worker=local_worker)\n",
    "\n",
    "from syft.workers.websocket_client import WebsocketClientWorker\n",
    "\n",
    "remote_client = WebsocketClientWorker(\n",
    "                            host = 'localhost',\n",
    "                            hook=hook,\n",
    "                            id=2, \n",
    "                            port=8181)\n",
    "\n",
    "hook.local_worker.add_worker(remote_client)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "yaap8ep0WbA3"
   },
   "source": [
    "# Step 3: Create Tensors & Send To The Worker"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "pQ9iQViMWbA5"
   },
   "outputs": [],
   "source": [
    "x = syft.FixedPrecisionTensor([1,3,5,7,9]).share(remote_client)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "Ao5OL3JsWbA7"
   },
   "outputs": [],
   "source": [
    "x2 = syft.FixedPrecisionTensor([2,4,6,8,10]).share(remote_client)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 34
    },
    "colab_type": "code",
    "id": "zfVc5_h5WbA-",
    "outputId": "4a6cbff9-1129-4dfa-bb5f-5260b51a22f1"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "FloatTensor[_PointerTensor - id:4129544610 owner:0 loc:2 id@loc:79320779676]"
      ]
     },
     "execution_count": 7,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 34
    },
    "colab_type": "code",
    "id": "uBUfHGk5WbBB",
    "outputId": "97d6dc33-4a95-4828-cf87-2bed16d09b8d"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "FloatTensor[_PointerTensor - id:8144291470 owner:0 loc:2 id@loc:19397969248]"
      ]
     },
     "execution_count": 8,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "pFQoIbF9WbBF"
   },
   "source": [
    "# Step 4: Execute Operations Like Normal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "i7xOloWOWbBG"
   },
   "outputs": [],
   "source": [
    "y = x + x2 + x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "hv6Ci9EpWbBK"
   },
   "source": [
    "# Step 5: Get Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 34
    },
    "colab_type": "code",
    "id": "JFXHDVvYWbBL",
    "outputId": "40a82592-f409-4f3a-9363-d02fa6d0bdb8"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "FloatTensor[_PointerTensor - id:1340811713 owner:0 loc:2 id@loc:1136221544]"
      ]
     },
     "execution_count": 10,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 136
    },
    "colab_type": "code",
    "id": "AIZYgjn3WbBO",
    "outputId": "4e3a27e5-98d8-4760-cf97-1206a8cd52b3"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\n",
       "  3\n",
       "  6\n",
       "  9\n",
       " 12\n",
       " 14\n",
       "[syft.core.frameworks.torch.tensor.FloatTensor of size 5]"
      ]
     },
     "execution_count": 11,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.get()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 136
    },
    "colab_type": "code",
    "id": "VEBZFX53WbBR",
    "outputId": "25a12c43-16e0-4c52-ec06-3ed487634740"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\n",
       "  3\n",
       "  6\n",
       "  9\n",
       " 12\n",
       " 14\n",
       "[syft.core.frameworks.torch.tensor.FloatTensor of size 5]"
      ]
     },
     "execution_count": 12,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "k61CHx_sWbBV"
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "collapsed_sections": [],
   "name": "WebsocketClientWorker.ipynb",
   "provenance": [],
   "toc_visible": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
